/*
 * @Author: 0x9DEFA478
 * @Date: 2021-09-20 16:59:48
 * @LastEditTime: 2021-12-17 23:08:40
 * @LastEditors: 0x9DEFA478
 * @Description: 
 * QQ:2652450237
 * ============================================================================================================================================
 * 
 * 
 * 
 *                                                                                               ************      ****************************
 *                                                                                             ************      ****************************  
 *                                                                                           ************      ****************************    
 *                                                                                         ************      ****************************      
 *                                                                                       ************      ************                        
 *                                                                                     ************      ************                          
 *                                                                                   ************      ************                            
 *                                                                                 ************      ************                              
 *                                                                               ************      ************                                
 *                                                                             ************      ************                                  
 *                                                                           ************      ************                                    
 *                                                                         ************      ************                                      
 *                                                                       ************      ************                                        
 *                                                                     ************      ************                                          
 *                                                                   ************      ************                                            
 *                                                                 ************      ************                                              
 *                                                               ************      ************                                                
 *                                                             ************      ************                                                  
 *                                                           ************      ************                                                    
 *                                                         ************      ************                                                      
 *                                                       ************      ************                                                        
 *                                                     ************      ************                                                          
 *                                                   ************      ************                                                            
 *                                                 ************      ************                                                              
 *                                               ************      ************                                                                
 *                                             ************      ************                                                                  
 *                                           ************      ************                                                                    
 *                                         ************      ************                                                                      
 *                                       ************      ************                                                                        
 *                                     ************      ************                                                                          
 *                                   ************      ************                                                                            
 *                                 ************      ************                                                                              
 *                               ************      ************                                                                                
 *                             ************      ************                                                                                  
 *                           ************      ************                                                                                    
 *                         ************      ************                                                                                      
 *       ****************************      ************                                                                                        
 *     ****************************      ************                                                                                          
 *   ****************************      ************                                                                                            
 * ****************************      ************                                                                                              
 * 
 * 
 * 
 * ============================================================================================================================================
 * 
 */
#include "IP_I2C.h"
#include "System/System.h"





static void MasterTransferRefresh(IP_I2C* ip_i2c){
  unsigned int RemainingSize;
  unsigned int Addr;
  int IsRead;
  volatile unsigned int isr;
  unsigned int cr2;
  
  isr=cIP_I2C_I2C(ip_i2c)->ISR;
  
  Addr=ip_i2c->TransStatus.Addr;

  if((Addr&0x01U)!=0){
    IsRead=-1;
    Addr&=0xFEU;
  }

  RemainingSize=ip_i2c->TransStatus.TxRemainingSize;
  if(RemainingSize>0){
    //发送

    if(RemainingSize>255){

      ip_i2c->TransStatus.TxRemainingSize=RemainingSize-255;

      cr2=I2C_CR2_RELOAD
      |(255U<<I2C_CR2_NBYTES_Pos)
      |((Addr<<I2C_CR2_SADD_Pos)&I2C_CR2_SADD_Msk);

    }else{
      ip_i2c->TransStatus.TxRemainingSize=0;

      cr2=
      ((RemainingSize<<I2C_CR2_NBYTES_Pos)&I2C_CR2_NBYTES_Msk)
      |((Addr<<I2C_CR2_SADD_Pos)&I2C_CR2_SADD_Msk);
      
    }
    if(ip_i2c->TransStatus.TxIsStartTransfer==0){
      ip_i2c->TransStatus.TxIsStartTransfer=-1;
      cIP_I2C_I2C(ip_i2c)->CR2=cr2|I2C_CR2_START;
    }else{
      cIP_I2C_I2C(ip_i2c)->CR2=cr2;
    }

  }else{

    RemainingSize=ip_i2c->TransStatus.RxRemainingSize;
    if((RemainingSize>0)&&(IsRead!=0)){
      //读取条件满足(接收传输并且接收数据大于0)

      if(RemainingSize>255){
        ip_i2c->TransStatus.RxRemainingSize=RemainingSize-255;

        cr2=I2C_CR2_RELOAD
        |(255U<<I2C_CR2_NBYTES_Pos)
        |I2C_CR2_RD_WRN
        |((Addr<<I2C_CR2_SADD_Pos)&I2C_CR2_SADD_Msk);

      }else{
        ip_i2c->TransStatus.RxRemainingSize=0;

        cr2=
        ((RemainingSize<<I2C_CR2_NBYTES_Pos)&I2C_CR2_NBYTES_Msk)
        |I2C_CR2_RD_WRN
        |((Addr<<I2C_CR2_SADD_Pos)&I2C_CR2_SADD_Msk);

      }
      if(ip_i2c->TransStatus.RxIsStartTransfer==0){
        ip_i2c->TransStatus.RxIsStartTransfer=-1;
        cIP_I2C_I2C(ip_i2c)->CR2=cr2|I2C_CR2_START;
      }else{
        cIP_I2C_I2C(ip_i2c)->CR2=cr2;
      }

    }else{
      //结束传输

      cIP_I2C_I2C(ip_i2c)->CR2|=I2C_CR2_STOP;

      while((cIP_I2C_I2C(ip_i2c)->ISR&I2C_ISR_STOPF)!=I2C_ISR_STOPF){
      }
      cIP_I2C_I2C(ip_i2c)->ICR=I2C_ICR_STOPCF;

      ip_i2c->TransStatus.IsBusy=0;
      ((void (*)(void*))ip_i2c->TransDoneCallback)(ip_i2c->v_TransDoneCallback);
    }
  }
  

}



/**
 * @brief 事件中断回调
 * @param ip_i2c IP_I2C句柄
 * @return 无
 */
void IP_I2C_EventIrqCallback(IP_I2C* ip_i2c){
  unsigned int isr;
  
  isr=cIP_I2C_I2C(ip_i2c)->ISR;
  if((isr&I2C_ISR_NACKF)!=0){
    cIP_I2C_I2C(ip_i2c)->ICR=I2C_ICR_NACKCF;

    cIP_I2C_rxDMA(ip_i2c)->CR&=(~DMA_SxCR_EN);//失能DMA
    cIP_I2C_txDMA(ip_i2c)->CR&=(~DMA_SxCR_EN);//失能DMA

    cIP_I2C_I2C(ip_i2c)->CR1&=(~I2C_CR1_PE);//失能I2C

    ip_i2c->TransStatus.Error=vIP_I2C_Error_NAK;
    ip_i2c->TransStatus.IsBusy=0;
    ((void (*)(void*))ip_i2c->TransDoneCallback)(ip_i2c->v_TransDoneCallback);

    return;
  }

  if((isr&(I2C_ISR_TC|I2C_ISR_TCR))!=0){
    if(ip_i2c->TransStatus.IsBusy!=0){
      MasterTransferRefresh(ip_i2c);
    }
  }
  

}

/**
 * @brief 错误中断回调
 * @param ip_i2c IP_I2C句柄
 * @return 无
 */
void IP_I2C_ErrorIrqCallback(IP_I2C* ip_i2c){
  unsigned int isr;
  
  isr=cIP_I2C_I2C(ip_i2c)->ISR;
  if(ip_i2c->TransStatus.IsBusy!=0){
    cIP_I2C_rxDMA(ip_i2c)->CR&=(~DMA_SxCR_EN);//失能DMA
    cIP_I2C_txDMA(ip_i2c)->CR&=(~DMA_SxCR_EN);//失能DMA

    cIP_I2C_I2C(ip_i2c)->CR1&=(~I2C_CR1_PE);//失能I2C

    if((isr&I2C_ISR_BERR)!=0){
      ip_i2c->TransStatus.Error=vIP_I2C_Error_BusError;
    }else if((isr&I2C_ISR_ARLO)!=0){
      ip_i2c->TransStatus.Error=vIP_I2C_Error_ArbitrationLost;
    }else if((isr&I2C_ISR_OVR)!=0){
      ip_i2c->TransStatus.Error=vIP_I2C_Error_Over;
    }else{
      ip_i2c->TransStatus.Error=vIP_I2C_Error_Unknow;
    }
    ip_i2c->TransStatus.IsBusy=0;
    ((void (*)(void*))ip_i2c->TransDoneCallback)(ip_i2c->v_TransDoneCallback);
  }

}

/**
 * @brief 中断回调 此方法为中断回调不能与IP_I2C_ErrorIrqCallback()或IP_I2C_EventIrqCallback()同时使用
 * @param ip_i2c IP_I2C句柄
 * @return 无
 */
void IP_I2C_IrqCallback(IP_I2C* ip_i2c){

  IP_I2C_ErrorIrqCallback(ip_i2c);
  IP_I2C_EventIrqCallback(ip_i2c);
}

/**
 * @brief 设置传输完成回调
 * @param ip_i2c IP_I2C对象
 * @param Callback 回调函数
 * @param v 回调函数传入的参数
 * @return 0:成功 其他:失败
 */
int IP_I2C_SetTransDoneCallback(IP_I2C* ip_i2c,void (*Callback)(void*),void* v){
  
  if(ip_i2c->TransStatus.IsBusy!=0){
    return -1;
  }
  ip_i2c->TransDoneCallback=Callback;
  ip_i2c->v_TransDoneCallback=v;

  return 0;
}

/**
 * @brief 进行I2C传输 在空闲时调用
 * @param ip_i2c IP_I2C句柄
 * @param Addr 目标地址 地址+读写位 读写位决定是否有读取 当最低位为1时 读取有效
 * @param TxData 发送的数据
 * @param TxLength 发送长度
 * @param RxData 如果读取数据 此段指向容纳读取数据的内存
 * @param RxLength 读取长度
 * @return 无
 */
void IP_I2C_MasterTransfer(IP_I2C* ip_i2c,unsigned char Addr,unsigned char* TxData,int TxLength,unsigned char* RxData,int RxLength){

  if(ip_i2c->TransStatus.IsBusy!=0){
    return;
  }

  ip_i2c->TransStatus.IsBusy=-1;
  ip_i2c->TransStatus.Error=vIP_I2C_Error_None;

  if((cIP_I2C_I2C(ip_i2c)->CR1&I2C_CR1_PE)==0){
    cIP_I2C_I2C(ip_i2c)->CR1|=I2C_CR1_PE;//使能I2C
  }

  while(cIP_I2C_I2C(ip_i2c)->ISR&I2C_ISR_BUSY){
  }

  ip_i2c->TransStatus.TxRemainingSize=TxLength;
  ip_i2c->TransStatus.TxIsStartTransfer=0;
  ip_i2c->TransStatus.RxRemainingSize=RxLength;
  ip_i2c->TransStatus.RxIsStartTransfer=0;
  ip_i2c->TransStatus.Addr=Addr;

  System_DataMemoryBarrier();

  cIP_I2C_txDMA(ip_i2c)->NDTR=(unsigned int)TxLength;
  cIP_I2C_txDMA(ip_i2c)->M0AR=(unsigned int)TxData;
  cIP_I2C_rxDMA(ip_i2c)->NDTR=(unsigned int)RxLength;
  cIP_I2C_rxDMA(ip_i2c)->M0AR=(unsigned int)RxData;


  oIP_DMA_ClearAllBit_IFCR(ip_i2c->Instance.DMA_Tx);
  oIP_DMA_ClearAllBit_IFCR(ip_i2c->Instance.DMA_Rx);

  
  if(RxLength>0){
    cIP_I2C_rxDMA(ip_i2c)->CR|=DMA_SxCR_EN;//使能DMA
  }
  if(TxLength>0){
    cIP_I2C_txDMA(ip_i2c)->CR|=DMA_SxCR_EN;//使能DMA
  }

  MasterTransferRefresh(ip_i2c);

}






